package com.sxr.integration.impl;

import com.sxr.file.FileHandler;
import com.sxr.file.FileRequest;
import com.sxr.file.FileResponse;
import com.sxr.integration.SecureFileRequest;
import com.sxr.integration.SecureFileService;
import com.sxr.integration.TenantContext;
import com.sxr.integration.plugin.RequestPlugin;
import com.sxr.integration.tenant.TenantConfigProvider;
import com.sxr.signature.SignRequest;
import com.sxr.signature.VerifyService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 默认安全文件服务实现
 * 整合签名验证和文件处理功能
 *
 * @author SXR
 * @since 1.0.0
 */
public class DefaultSecureFileService implements SecureFileService {

    private final VerifyService verifyService;
    private final FileHandler fileHandler;
    private final TenantConfigProvider tenantConfigProvider;
    private final List<RequestPlugin> plugins;

    /**
     * 构造函数 - 使用指定的租户配置提供者
     */
    public DefaultSecureFileService(VerifyService verifyService, FileHandler fileHandler, TenantConfigProvider tenantConfigProvider) {
        this.verifyService = verifyService;
        this.fileHandler = fileHandler;
        this.tenantConfigProvider = tenantConfigProvider;
        this.plugins = new ArrayList<>();
    }



    @Override
    public FileResponse handleSecureDownload(SecureFileRequest request) {
        return handleSecureRequest(request, false);
    }

    @Override
    public FileResponse handleSecurePreview(SecureFileRequest request) {
        return handleSecureRequest(request, true);
    }

    /**
     * 处理安全请求的通用方法
     */
    private FileResponse handleSecureRequest(SecureFileRequest request, boolean isPreview) {
        if (request == null) {
            return FileResponse.error(400, "Invalid request");
        }

        try {
            // 获取租户上下文
            TenantContext tenantContext = getTenantContext(request.getTenantId());
            if (tenantContext == null) {
                return FileResponse.error(404, "Tenant not found");
            }

            // 执行插件预处理
            if (!executePrePlugins(request, tenantContext)) {
                return FileResponse.forbidden();
            }

            // 检查是否过期
            if (isExpired(request)) {
                return FileResponse.error(410, "Request expired");
            }

            // 需要添加校验机制。
            if (!skipVerify(request, tenantContext)) {
                // 检查文件扩展名
                if (!isExtensionAllowed(request, tenantContext)) {
                    return FileResponse.error(403, "File type not allowed");
                }
                // 验证签名
                if (!verifySignature(request, tenantContext)) {
                    return FileResponse.error(401, "Invalid signature");
                }
            }


            // 构建文件请求
            FileRequest fileRequest = buildFileRequest(request, isPreview);

            // 处理文件请求
            FileResponse response;
            if (isPreview) {
                response = fileHandler.handlePreview(fileRequest);
            } else {
                response = fileHandler.handleDownload(fileRequest);
            }

            // 执行插件后处理
            executePostPlugins(request, response, tenantContext);

            return response;

        } catch (Exception e) {
            return FileResponse.internalError("Failed to process request: " + e.getMessage());
        }
    }

    /**
     * 验证签名
     */
    private boolean verifySignature(SecureFileRequest request, TenantContext tenantContext) {
        if (request.getSignature() == null) {
            return false;
        }

        // 构建签名请求
        SignRequest signRequest = buildSignRequest(request);
        signRequest.setSecretKey(tenantContext.getSecretKey());

        // 重新生成签名进行比较
//        String expectedSignature = signatureService.verifySignature(signRequest);
        return verifyService.verifySignature(signRequest,request.getSignature());
    }

    /**
     * 检查是否过期
     */
    private boolean isExpired(SecureFileRequest request) {
        if (request.getExpireTime() == null) {
            return false;
        }
        return System.currentTimeMillis() > request.getExpireTime();
    }

    /**
     * 扩展跳过校验
     */
    private boolean skipVerify(SecureFileRequest request, TenantContext tenantContext) {
        String extension = request.getFileExtension();
        if (extension == null) {
            return false; // 没有扩展名，默认允许
        }

        String lowerExt = extension.toLowerCase();

        String[] whiteExtensions = tenantContext.getWhiteExtensions();
        if( whiteExtensions != null ){
            for (String whiteExtension : whiteExtensions) {
                if (lowerExt.equals(whiteExtension.toLowerCase())) {
                    return true;
                }
            }
        }

        return false; //
    }

    /**
     * 检查文件扩展名是否被允许
     */
    private boolean isExtensionAllowed(SecureFileRequest request, TenantContext tenantContext) {
        String extension = request.getFileExtension();
        if (extension == null) {
            return true; // 没有扩展名，默认允许
        }
        return tenantContext.isExtensionAllowed(extension);
    }

    /**
     * 构建签名请求
     */
    private SignRequest buildSignRequest(SecureFileRequest request) {
        SignRequest signRequest = new SignRequest();
        signRequest.setTenantId(request.getTenantId());
        signRequest.setFilePath(request.getFilePath());
        signRequest.setExpireTime(request.getExpireTime());
        signRequest.setAccessLimit(request.getAccessLimit());
        // 注意：preview参数不参与签名计算，使同一个签名可以用于预览和下载
        // 注意：clientIp不参与签名计算，避免用户切换网络时签名失效
        // signRequest.setClientIp(request.getClientIp());
        signRequest.setExtraParams(request.getExtraParams());
        return signRequest;
    }

    /**
     * 构建文件请求
     */
    private FileRequest buildFileRequest(SecureFileRequest request, boolean isPreview) {
        FileRequest fileRequest = new FileRequest();
        fileRequest.setTenantId(request.getTenantId());
        fileRequest.setFilePath(request.getFilePath());
        fileRequest.setFileName(request.getFileName());
        fileRequest.setPreview(isPreview);
        fileRequest.setRangeHeader(request.getRangeHeader());
        fileRequest.setClientIp(request.getClientIp());
        fileRequest.setUserAgent(request.getUserAgent());
        fileRequest.setHeaders(request.getHeaders());
        return fileRequest;
    }



    /**
     * 获取租户上下文
     * 使用配置提供者获取租户信息，支持动态配置
     */
    private TenantContext getTenantContext(String tenantId) {
        return tenantConfigProvider.getTenantContext(tenantId);
    }

    /**
     * 执行插件预处理
     */
    private boolean executePrePlugins(SecureFileRequest request, TenantContext context) {
        for (RequestPlugin plugin : plugins) {
            try {
                if (!plugin.preHandle(request, context)) {
                    return false;
                }
            } catch (Exception e) {
                // 插件异常不应该影响主流程，记录日志即可
            }
        }
        return true;
    }

    /**
     * 执行插件后处理
     */
    private void executePostPlugins(SecureFileRequest request, FileResponse response, TenantContext context) {
        for (RequestPlugin plugin : plugins) {
            try {
                plugin.postHandle(request, response, context);
            } catch (Exception e) {
                // 插件异常不应该影响主流程，记录日志即可
            }
        }
    }

    /**
     * 添加插件
     */
    public void addPlugin(RequestPlugin plugin) {
        if (plugin != null) {
            plugins.add(plugin);
            // 按优先级排序
            Collections.sort(plugins, Comparator.comparingInt(RequestPlugin::getOrder));
        }
    }

    /**
     * 移除插件
     */
    public void removePlugin(String pluginName) {
        plugins.removeIf(plugin -> plugin.getName().equals(pluginName));
    }
}
